using System;
using System.Collections.Generic;
using System.Text;
using C4F.DevKit.Bluetooth.ServiceAndDeviceDiscovery;
using System.Threading;
using System.Net.Sockets;

namespace SerialPortService
{
    public class SerialPortService : LocalService
    {
        Thread helperThread;
        bool listening;
        ServiceHandle sh;

        public delegate void SerialDataEventHandler(object sender, SerialDataEventArgs e);
        public event EventHandler NewClientConnected;
        public event EventHandler ClientDisconnected;
        public event SerialDataEventHandler DataReceivedFromClient;
        public event SerialDataEventHandler DataSentToClient;

        public void Register()
        {
            sh = Register(ServiceType.SerialPortProfile, "SPP Service", "Serial Port Profile Service");
            listening = true;
            helperThread = new Thread(ThreadFunction);
            helperThread.Start();
        }
        
        public override void UnRegister()
        {
            listening = false;
            base.UnRegister();
        }

        private void ThreadFunction()
        {
            while (listening)
            {
                // Wait for incoming connections
                while (listening && !sh.ConnectionsPending())
                    System.Threading.Thread.Sleep(10);

                if (!listening)
                    break;

                // accept a waiting connection.
                NetworkStream ns = sh.AcceptConnection();

                // Raise the NewClientConnected event.
                if (NewClientConnected != null)
                    NewClientConnected(this, new EventArgs());

                try
                {
                    const int bufferSize = 4096;

                    while (listening)
                    {
                        byte[] buffer;

                        // write to the client.
                        string dataSent = "Hello from " + this.Name;
                        buffer = Encoding.ASCII.GetBytes(dataSent);
                        ns.Write(buffer, 0, buffer.Length);

                        // Raise the DataSentToClient event.
                        if (DataSentToClient != null)
                            DataSentToClient(this, new SerialDataEventArgs(dataSent));

                        // read the client's response.
                        buffer = new byte[bufferSize];
                        int length = ns.Read(buffer, 0, buffer.Length);
                        string dataReceived = Encoding.ASCII.GetString(buffer, 0, length);

                        // Raise the DataReceivedFromClient event.
                        if (DataReceivedFromClient != null)
                            DataReceivedFromClient(this, new SerialDataEventArgs(dataReceived));
                    }
                }
                catch
                {
                    ns.Close();
                }

                if (ClientDisconnected != null)
                    ClientDisconnected(this, new EventArgs());
                Thread.Sleep(1000);
            }
        }
    }
}